#include <iostream>
#include <pthread.h>
#include <vector>
#include <cassert>
#include <unistd.h>
#include <cstring>
using namespace std;

// class ThreadData//包含线程信息的结构体
// {
// public:
//     pthread_t tid;
//     char namebuffer[64];

// };
// class Threadnumber
// {
//     public:
//     int exit_code;
//     int exit_result;
// };

// //static_routine被多个线程同时执行且没有产生异常和二义性-->可重入函数
// //像cnt,td这种在函数内定义的变量是局部变量，具有临时性。它们是线程独属的栈结构
// void* static_routine(void * args)
// {
//     ThreadData* td=static_cast<ThreadData*>(args);//安全转型
//     int cnt=10;
//     while (cnt)
//     {
//         cout << "cnt: " << cnt << " &cnt: " << &cnt << endl;
//         cnt--;
//         sleep(1);
       
//     }
//     //delete td;//避免野指针问题，这里只使用，不销毁
//     //pthread_exit(nullptr);
//     // Threadnumber* tb= new Threadnumber();
//     // tb->exit_code=10;
//     // tb->exit_result=100;
//     // return (void*)tb;//右值

//     //不能在栈上开辟Threadnumber tb，函数退出时自动释放栈帧

// }
// // void* static_routine(void * args)
// // {
// //     string name=static_cast<const char*>(args);//安全转型
// //     while (true)
// //     {
// //         cout<<"new thread create success,name "<<name<<endl;
// //         sleep(1);

// //         // //检测线程间影响
// //         // int* p=nullptr;
// //         // *p=10;//野指针解引用，引发11号信号
// //     }
    
// // }

// /*****3*******/


// int main()
// {
//         //创建多个线程
//     vector<ThreadData*> threads;
// #define NUM 10
//     for(int i=0;i<NUM;++i)
//     {
        
//         //创建线程信息对象
//         ThreadData* td=new ThreadData();
//         //格式化写入
//         snprintf(td->namebuffer,sizeof(td->namebuffer),"%s:%d","thread",i+1);
//         //每一个线程都有一个对象，并将对象的地址“拷贝”给函数的形参，这样每个线程都有自己的namebuffer
//         //并且传到函数里面的td与主线程中的td没有关系
        
//         //由于td已经是一个指针，并且是对结构体内容操作，这里不需要&td,虽然接受的形参也对不上
//         //小编当时在编写的时候由于指针理解问题，纠结了一会
//         pthread_create(&td->tid,nullptr,static_routine,td);
//         threads.push_back(td);
//     }

//     // for(auto &iter:threads)
//     // {
//     //     cout<<"create "<<iter->namebuffer<<" : "<<iter->tid<<" success"<<endl;
//     // }
//     sleep(5);
//     for(int i = 0; i < threads.size()/2; i++)//线程如果是被取消的，退出码：-1
//     {
//         pthread_cancel(threads[i]->tid);
//         cout << "pthread_cancel : " << threads[i]->namebuffer << " success" << endl;
//     }

//     ///线程等待

//     for(auto& iter:threads)
//     {
//         void* ret=nullptr;
//         //Threadnumber* ret=nullptr;
//         int n=pthread_join(iter->tid,(void** )&ret); //&ret-->void** |*(&ret)就是static_routine函数返回值
//         assert(n==0);
//         //cout<<"join "<<iter->namebuffer<<ret->exit_code<<"***"<<ret->exit_result<<endl;
//         cout<<"join "<<iter->namebuffer<<"***"<<(long long)ret<<endl;


//         //不在static_routine释放的原因：主线程与新线程是并行交叉运行的，执行到这一步有可能
//         //部分线程资源已经被释放，对已经释放资源的指针解引用会引发错误
//         delete iter;//外部统一申请，统一释放
//     }
//     cout<<"main thread quit"<<endl;


//     return 0;
// }





// /* ********2*******/

// // int main()
// // {
// //     //创建多个线程
// //     vector<pthread_t*> tids;
// // #define NUM 10
// //     for(int i=0;i<NUM;++i)
// //     {
// //         pthread_t tid;
// //         char namebuffer[64];
// //         snprintf(namebuffer,sizeof(namebuffer),"%s:%d","thread",i+1);
// //         pthread_create(&tid,nullptr,static_routine,namebuffer);
// //     }


// //     while (true)
// //     {
// //         cout<<"main thread create success,name mainthread"<<endl;
// //         sleep(1);
// //     }












// /********1***********/
//     // pthread_t id;
//     // pthread_create(&id,nullptr,static_routine,(void*)"new");

//     // while (true)
//     // {
//     //     cout<<"main thread create success,name main"<<endl;
//     //     sleep(1);
//     // }
    
//     // return 0;
// //}

//添加__thread，可以将一个内置类型设置为线程局部存储
__thread int g_val = 100;
std::string changeId(const pthread_t &thread_id)
{
    char tid[128];
    snprintf(tid, sizeof(tid), "0x%x", thread_id);
    return tid;
}

void *start_routine(void *args)
{
    std::string threadname = static_cast<const char *>(args);
    // pthread_detach(pthread_self()); //设置自己为分离状态

    int cnt = 5;
    while (true)
    {
        std::cout << threadname<<" g_val: "<< g_val << " &g_val: " << &g_val << std::endl;
        sleep(1);
        g_val++;
    }

    return nullptr;
}
int  main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start_routine, (void *)"new  thread");
    std::string main_id = changeId(pthread_self());
    pthread_detach(tid);

    //std::cout << "main thread running ... new thread id: " << changeId(tid) <<" main thread id: " << main_id << std::endl;

    // sleep(5);
    // 一个线程默认是joinable的，如果设置了分离状态，不能够进行等待了
    // int n = pthread_join(tid, nullptr);
    // std::cout << "result: " << n << " : " <<strerror(n) << std::endl;

    while(true)
    {
        std::cout << "main thread"<< " g_val: "<< g_val << " &g_val: " << &g_val << std::endl;
        sleep(1);
    }
    return 0;
}


